home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / win_sdk / dde / clidata.c next >
Encoding:
C/C++ Source or Header  |  1990-06-01  |  21.0 KB  |  826 lines

  1. /****************************************************************************
  2.  
  3.     MODULE: CLIDATA.C
  4.  
  5.     PURPOSE: Maintains conversation data and paints data in the client
  6.          application window.
  7.  
  8. ****************************************************************************/
  9.  
  10. #include "windows.h"
  11. #include "clires.h"
  12. #include "client.h"
  13. #include <string.h>
  14. #include <stdlib.h>
  15.  
  16. typedef struct ITEM
  17. {
  18.     char szItem[ITEM_MAX_SIZE+1];
  19.     char szValue[VALUE_MAX_SIZE+1];
  20. };
  21.  
  22. typedef struct CONV
  23. {
  24.     BOOL  bInTerminate;
  25.     enum PENDINGACK ePendingAck;  
  26.     HWND  hwndClientDDE;
  27.     HWND  hwndServerDDE;
  28.     char  szApplication[APP_MAX_SIZE+1];
  29.     char  szTopic[TOPIC_MAX_SIZE+1];
  30.     int   nItemCount;
  31.     struct ITEM Item[ITEMS_PER_CONV_MAX_COUNT];
  32. };
  33.  
  34. static struct CONV Conv[CONV_MAX_COUNT];
  35. static int   nConvCount = 0;
  36. static HWND  hwndNewClientDDE; /* used by SelectNewConvDlgProc */
  37. static HWND  hwndNewServerDDE; /* new conversation selected by user */
  38.  
  39. static char  szSelectedApplication[APP_MAX_SIZE+1];
  40. static char  szSelectedTopic[TOPIC_MAX_SIZE+1];
  41. static char  szSelectedItem[ITEM_MAX_SIZE+1];
  42. static char  szSelectedValue[VALUE_MAX_SIZE+1];
  43.  
  44. static struct CONV * NEAR FindConv(HWND);
  45. static struct ITEM * NEAR FindItem(HWND, char *);
  46.     
  47. BOOL FAR PASCAL SelectNewConvDlgProc(HWND, unsigned, WORD, LONG);
  48.  
  49. /*****************************************************************
  50.  
  51.     FUNCTION: AddItemToConv
  52.  
  53.     PURPOSE:  Add a data item to an existing conversation.
  54.  
  55. *****************************************************************/
  56. BOOL AddItemToConv(hwndClientDDE, szItem)
  57.     HWND   hwndClientDDE;
  58.     char * szItem;
  59. {
  60.     struct CONV * pConv;
  61.     struct ITEM * pItem;
  62.  
  63.     if (!(pConv = FindConv(hwndClientDDE)))
  64.         return (FALSE);
  65.     if (pConv->nItemCount >= ITEMS_PER_CONV_MAX_COUNT)
  66.         return (FALSE);
  67.    pItem =  pConv->Item + pConv->nItemCount++;
  68.    strcpy(pItem->szItem, szItem);
  69.    pItem->szValue[0] = 0;
  70.    return (TRUE);
  71. }
  72.  
  73.  
  74.  
  75.  
  76. /**********************************************************
  77.  
  78.     FUNCTION:  AtLeastOneConvActive
  79.  
  80.     PURPOSE:   Used during termination of application, to
  81.            determine whether pending DDE terminations
  82.            have completed.
  83.  
  84. ***********************************************************/
  85. BOOL AtLeastOneConvActive()
  86. {
  87.     return (nConvCount? TRUE: FALSE);
  88. }
  89.  
  90.  
  91.  
  92. /*****************************************************************
  93.  
  94.     FUNCTION: AddConv
  95.  
  96.     PURPOSE:  Initialize items in CONV structure.
  97.  
  98. *****************************************************************/
  99. BOOL AddConv(hwndClientDDE, hwndServerDDE, szApplication, szTopic)
  100.     HWND  hwndClientDDE;
  101.     HWND  hwndServerDDE;
  102.     char * szApplication;
  103.     char * szTopic;
  104. {
  105.     struct CONV * pConv;
  106.  
  107.     if (nConvCount >= CONV_MAX_COUNT)
  108.         return (FALSE);
  109.     pConv = Conv + nConvCount++;
  110.     pConv->bInTerminate = FALSE;
  111.     pConv->ePendingAck = NONE;
  112.     pConv->hwndClientDDE = hwndClientDDE;
  113.     pConv->hwndServerDDE = hwndServerDDE;
  114.     strcpy(pConv->szApplication, szApplication);
  115.     strcpy(pConv->szTopic, szTopic);
  116.     pConv->nItemCount = 0;
  117.     return (TRUE);
  118. }
  119.  
  120.  
  121.  
  122. /*****************************************************************
  123.  
  124.     FUNCTION: DoesAdviseAlreadyExist
  125.  
  126.     PURPOSE:  Determines whether hot/warm link has already been
  127.           established for specified conversation item.
  128.  
  129. *****************************************************************/
  130. BOOL DoesAdviseAlreadyExist(hwndClientDDE, szItem)
  131.     HWND hwndClientDDE;
  132.     char * szItem;
  133. {
  134.     return (FindItem(hwndClientDDE,szItem)==NULL?FALSE:TRUE);
  135. }
  136.  
  137.  
  138.  
  139. /*****************************************************************
  140.  
  141.     FUNCTION: FindItem
  142.  
  143.     PURPOSE:  Return pointer to item structure given conversation and item.
  144.  
  145. *****************************************************************/
  146. struct ITEM * NEAR FindItem(hwndClientDDE, szItem)
  147.     HWND hwndClientDDE;
  148.     char * szItem;
  149. {
  150.     struct CONV * pConv;
  151.     struct ITEM * pItem;
  152.     int           nItemIndex;
  153.  
  154.     if (!(pConv = FindConv(hwndClientDDE)))
  155.         return (NULL);
  156.     for (pItem = pConv->Item, nItemIndex = 0;
  157.      nItemIndex < pConv->nItemCount;
  158.          pItem++, nItemIndex++)
  159.     {
  160.         if (!strcmpi(szItem, pItem->szItem))
  161.         {
  162.             return (pItem);
  163.         }
  164.     }
  165.     return (NULL);
  166. }
  167.  
  168.  
  169. /*****************************************************************
  170.  
  171.     FUNCTION: FindConv
  172.  
  173.     PURPOSE:  Return pointer to conversation structure given handle
  174.           to client DDE window.
  175.  
  176. *****************************************************************/
  177. struct CONV * NEAR FindConv(hwndClientDDE)
  178.     HWND  hwndClientDDE;
  179. {
  180.     struct CONV * pConv;
  181.     int       nConvIndex;
  182.  
  183.     for (pConv = Conv, nConvIndex = 0;
  184.      nConvIndex < nConvCount;
  185.      pConv++, nConvIndex++)
  186.     {
  187.     if (pConv->hwndClientDDE == hwndClientDDE)
  188.         return (pConv);
  189.     }
  190.     return (NULL);
  191. }
  192.  
  193.  
  194. /***************************************************************
  195.  
  196.     FUNCTION:  FindConvGivenAppTopic
  197.  
  198.     PURPOSE:   Find handle of client DDE window given
  199.            application and topic for an active conversation.
  200.  
  201. ***************************************************************/
  202. HWND FindConvGivenAppTopic(szApp, szTopic)
  203.     char * szApp;
  204.     char * szTopic;
  205. {
  206.     struct CONV * pConv;
  207.     int       nConvIndex;
  208.  
  209.     for (pConv = Conv, nConvIndex = 0;
  210.      nConvIndex < nConvCount;
  211.      pConv++, nConvIndex++)
  212.     {
  213.      if (!(stricmp(pConv->szApplication, szApp))
  214.          && !(stricmp(pConv->szTopic, szTopic)))
  215.      {
  216.          return pConv->hwndClientDDE;
  217.      }
  218.     }
  219.     return NULL;
  220. }
  221.  
  222.  
  223. /*****************************************************************
  224.  
  225.     FUNCTION: GetAppAndTopic
  226.  
  227.     PURPOSE:  Get conversation's application and topic strings.
  228.  
  229. *****************************************************************/
  230. void GetAppAndTopic(hwndClientDDE, szApp, szTopic)
  231.     HWND  hwndClientDDE;
  232.     char * szApp;
  233.     char * szTopic;
  234. {
  235.     struct CONV * pConv;
  236.    
  237.     if (!(pConv = FindConv(hwndClientDDE)))
  238.         return;
  239.     strcpy(szApp, pConv->szApplication);
  240.     strcpy(szTopic, pConv->szTopic);
  241.     return;
  242. }
  243.  
  244.  
  245.  
  246. /****************************************************************
  247.  
  248.     FUNCTION: GetConvPendingAck
  249.  
  250.     PURPOSE:  Return state of acknowledgement for specified
  251.           conversation.
  252.  
  253. ****************************************************************/
  254. enum PENDINGACK GetConvPendingAck(hwndClientDDE)
  255.     HWND hwndClientDDE;
  256. {
  257.     struct CONV * pConv;
  258.  
  259.     if (pConv = FindConv(hwndClientDDE))
  260.     return pConv->ePendingAck;
  261.     else
  262.         return NONE;
  263. }
  264.  
  265.  
  266.  
  267. /*****************************************************************
  268.  
  269.     FUNCTION: GetHwndServerDDE
  270.  
  271.     PURPOSE:  Gets the hwnd of the server, given the handle of
  272.           the client DDE window.
  273.  
  274. *****************************************************************/
  275. HWND GetHwndServerDDE(hwndClientDDE)
  276.     HWND  hwndClientDDE;
  277. {
  278.     struct CONV * pConv;
  279.     int  nConvIndex;
  280.  
  281.     for (pConv = Conv, nConvIndex = 0;
  282.      nConvIndex < nConvCount;
  283.      pConv++, nConvIndex++)
  284.     {
  285.     if (pConv->hwndClientDDE == hwndClientDDE)
  286.         return (pConv->hwndServerDDE);
  287.     }
  288.     return (NULL);
  289. }
  290.  
  291.  
  292.  
  293. /*****************************************************************
  294.  
  295.     FUNCTION: GetNextConv
  296.  
  297.     PURPOSE:  Get next conversation in the list of current conversations.
  298.           To get the first conversation, pass a NULL hwnd.
  299.  
  300. *****************************************************************/
  301. HWND GetNextConv(hwndClientDDE)
  302.     HWND hwndClientDDE;
  303. {
  304.     struct CONV * pConv;
  305.     int       nConvIndex;
  306.  
  307.     if (hwndClientDDE)
  308.     {
  309.     for (nConvIndex = 0, pConv = Conv;
  310.          nConvIndex < nConvCount;
  311.          nConvIndex++, pConv++)
  312.         {
  313.         if (pConv->hwndClientDDE == hwndClientDDE)
  314.             {
  315.         if (++nConvIndex < nConvCount)
  316.             return (++pConv)->hwndClientDDE;
  317.                 else
  318.                     return (NULL);
  319.             }
  320.         }
  321.         return (NULL);
  322.     }
  323.     if (nConvCount > 0)
  324.     return (Conv[0].hwndClientDDE);
  325.     else
  326.         return (NULL);
  327. }
  328.  
  329.  
  330.  
  331. /****************************************************************
  332.  
  333.     FUNCTION: HexToInt
  334.  
  335.     PURPOSE:  Convert from ascii to integer up to 4 chars
  336.           representing a hexidecimal number.  The hex number
  337.           is considered terminated by a null or any non-hex
  338.           digit.
  339.  
  340. ****************************************************************/
  341. int HexToInt(szHex)
  342.     char * szHex;
  343. {
  344.     unsigned int  nReturn;
  345.     int       nDigit;
  346.     int       nIndex;
  347.  
  348.     nReturn = 0;
  349.     for (nIndex = 0; nIndex < 4; nIndex++)
  350.     {
  351.     if (*szHex >= '0' && *szHex <= '9')
  352.         nDigit = *szHex - '0';
  353.     else if (*szHex >= 'A' && *szHex <= 'F')
  354.         nDigit = *szHex - 'A' + 10;
  355.     else if (*szHex >= 'a' && *szHex <= 'f')
  356.         nDigit = *szHex - 'a' + 10;
  357.     else
  358.         return ((int)nReturn);
  359.     nReturn = (nReturn<<4) + nDigit;
  360.     szHex++;
  361.     }
  362.     return ((int)nReturn);
  363. }
  364.  
  365.  
  366.  
  367.  
  368. /****************************************************************
  369.  
  370.     FUNCTION: IsConvInTerminateState
  371.  
  372.     PURPOSE:  Determine whether conversation is in process of
  373.           being terminated.   In identifying the conversation,
  374.           it is necessary to compare both the hwndClientDDE
  375.           and hwndServerDDE, because during an initiate,
  376.           there may be multiple unwanted conversations sharing
  377.           the same hwndClientDDE.
  378.  
  379. ****************************************************************/
  380. BOOL IsConvInTerminateState(hwndClientDDE, hwndServerDDE)
  381.     HWND hwndClientDDE;
  382.     HWND hwndServerDDE;
  383. {
  384.     struct CONV * pConv;
  385.     int  nConvIndex;
  386.  
  387.     for (nConvIndex = 0, pConv = Conv;
  388.      nConvIndex < nConvCount;
  389.      nConvIndex++, pConv++)
  390.     {
  391.     if (pConv->hwndClientDDE == hwndClientDDE
  392.         && pConv->hwndServerDDE == hwndServerDDE)
  393.         return pConv->bInTerminate;
  394.     }
  395.     return (TRUE);  /* If conversation not found, assume terminate state */
  396.             /* to avoid possible endless terminate feedback loop */
  397. }
  398.  
  399.  
  400.  
  401. /****************************************************************
  402.  
  403.     FUNCTION: IsHwndClientDDEUsed
  404.  
  405.     PURPOSE:  Determine whether hwndClientDDE is still being
  406.           used in some second conversation after the
  407.           first conversation has been terminated.  This
  408.           determination is necessary during an initiate
  409.           in which the same hwndClientDDE is used in
  410.           multiple WM_DDE_INITIATE messages.
  411.           being terminated.
  412.  
  413. ****************************************************************/
  414. BOOL IsHwndClientDDEUsed(hwndClientDDE)
  415.     HWND  hwndClientDDE;
  416. {
  417.     struct CONV * pConv;
  418.     int  nConvIndex;
  419.  
  420.     for (pConv = Conv, nConvIndex = 0;
  421.      nConvIndex < nConvCount;
  422.      pConv++, nConvIndex++)
  423.     {
  424.     if (pConv->hwndClientDDE == hwndClientDDE)
  425.         return (TRUE);
  426.     }
  427.     return (FALSE);
  428. }
  429.  
  430.  
  431.  
  432. /****************************************************************
  433.  
  434.     FUNCTION: LetUserPickConversation
  435.  
  436.     PURPOSE:  The client has initiated possibly multiple
  437.           conversations (if a wild card application or topic
  438.           was specified in the WM_DDE_INITIATE).  This function
  439.           determines whether multiple servers established
  440.           conversations with the specified hwndClientDDE.
  441.           If so, this function asks the user to pick one of
  442.           the conversations, and terminates the other
  443.           conversations.
  444.  
  445. ****************************************************************/
  446. BOOL LetUserPickConversation(hwndClientDDE)
  447.     HWND  hwndClientDDE;
  448. {
  449.     struct CONV * pConv;
  450.     FARPROC  lpfnDlgProc;
  451.     int  nCountSameWnd;
  452.     int  nConvIndex;
  453.  
  454.     nCountSameWnd = 0;
  455.     for (pConv = Conv, nConvIndex = 0;
  456.      nConvIndex < nConvCount;
  457.      pConv++, nConvIndex++)
  458.     {
  459.     if (pConv->hwndClientDDE == hwndClientDDE)
  460.         nCountSameWnd++;
  461.     }
  462.     if (nCountSameWnd == 1)
  463.     return (TRUE);
  464.     if (nCountSameWnd == 0)
  465.     return (FALSE);
  466.     hwndNewServerDDE = NULL;
  467.     hwndNewClientDDE = hwndClientDDE; /* make known to SelectNewConvDlgProc */
  468.     /* Dialog proc SelectNewConvDlgProc is defined in this module */
  469.     lpfnDlgProc = MakeProcInstance(SelectNewConvDlgProc, hInst);
  470.     DialogBox(hInst,
  471.           "SelectNewConversation",
  472.           hwndMain,
  473.           lpfnDlgProc);
  474.     FreeProcInstance(lpfnDlgProc);
  475.  
  476.     /* Terminate unwanted conversations.  The only conversation  */
  477.     /* wanted is the one (hwndNewServerDDE) selected by the user */
  478.     /* in the SelectNewConv dialog box.              */
  479.  
  480.     for (pConv = Conv, nConvIndex = 0;
  481.      nConvIndex < nConvCount;
  482.      pConv++, nConvIndex++)
  483.     {
  484.     if (pConv->hwndClientDDE == hwndClientDDE
  485.         && pConv->hwndServerDDE != hwndNewServerDDE)
  486.     {
  487.         SendTerminate(hwndClientDDE, pConv->hwndServerDDE);
  488.     }
  489.     }
  490.     return (TRUE);
  491.  
  492. }
  493.  
  494.  
  495. /****************************************************************
  496.  
  497.     FUNCTION: PaintConvData
  498.  
  499.     PURPOSE:  Paint the client application window, using all
  500.           conversation/item information.
  501.  
  502. ****************************************************************/
  503. void PaintConvData(hwnd)
  504.     HWND  hwnd;
  505. {
  506.     HDC  hDC;
  507.     PAINTSTRUCT ps;
  508.     int  x,y;
  509.     int  nConvIndex, nItemIndex;
  510.     struct CONV * pConv;
  511.     struct ITEM * pItem;
  512.     char          szNumber[10];
  513.  
  514.     BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
  515.     hDC = ps.hdc;
  516.     
  517.     y = yDelta/2;  /* start 1/2 line down window */
  518.  
  519.     for (pConv = Conv, nConvIndex = 0;
  520.      nConvIndex < nConvCount;
  521.      pConv++, nConvIndex++)
  522.     {
  523.     x = xDelta/2;    /* start 1/2 char across window */
  524.         TextOut(hDC, x, y, 
  525.         (LPSTR)pConv->szApplication,
  526.         strlen(pConv->szApplication));
  527.         x += ((3+APP_MAX_SIZE)*xDelta);
  528.         TextOut(hDC, x, y,
  529.         (LPSTR)pConv->szTopic,
  530.         strlen(pConv->szTopic));
  531.         x += ((3+TOPIC_MAX_SIZE) *xDelta);
  532.     itoa(pConv->hwndClientDDE, szNumber, 16);
  533.     strupr(szNumber);
  534.         TextOut(hDC, x, y, (LPSTR)szNumber, strlen(szNumber));
  535.         y += yDelta;
  536.  
  537.     for (pItem = pConv->Item, nItemIndex = 0;
  538.          nItemIndex < pConv->nItemCount;
  539.              pItem++, nItemIndex++)
  540.         {
  541.             x = 4 * xDelta;   /* Indent items 4 spaces */
  542.             TextOut(hDC, x, y,
  543.                 (LPSTR)pItem->szItem,
  544.                 strlen(pItem->szItem));
  545.             x += ((3+ITEM_MAX_SIZE)*xDelta);
  546.             TextOut(hDC, x, y,
  547.                 (LPSTR)pItem->szValue,
  548.                 strlen(pItem->szValue));
  549.             y += yDelta;
  550.         }
  551.  
  552.     }
  553.          
  554.     ValidateRect(hwnd, (LPRECT)NULL);
  555.     EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
  556.  
  557.     return;
  558. }
  559.  
  560.  
  561.  
  562. /*****************************************************************
  563.  
  564.     FUNCTION: RemoveItemFromConv
  565.  
  566.     PURPOSE:  Remove an item (advise) from an existing conversation.
  567.  
  568. *****************************************************************/
  569. BOOL RemoveItemFromConv(hwndClientDDE, szItem)
  570.     HWND   hwndClientDDE;
  571.     char * szItem;
  572. {
  573.     struct CONV * pConv;
  574.     int           nItemIndex;
  575.     struct ITEM * pItem;
  576.  
  577.     if (!(pConv = FindConv(hwndClientDDE)))
  578.         return (FALSE);
  579.     pItem = pConv->Item;
  580.     nItemIndex = 0;
  581.     while (nItemIndex < pConv->nItemCount)
  582.     {
  583.         if (!(strcmpi(pItem->szItem, szItem)))
  584.             break;
  585.         pItem++;
  586.         nItemIndex++;
  587.     }
  588.     pConv->nItemCount--;
  589.     while (nItemIndex < pConv->nItemCount)
  590.     {
  591.         *pItem = *(pItem+1);
  592.         pItem++;
  593.         nItemIndex++;
  594.     }
  595.     return (TRUE);
  596. }
  597.  
  598.  
  599.  
  600. /*****************************************************************
  601.  
  602.     FUNCTION: RemoveConv
  603.  
  604.     PURPOSE:  Remove active conversation.   It is necessary to
  605.           specify both the client and server DDE windows,
  606.           since during an initiate, only the server DDE
  607.           window handles are distinguishable.
  608.  
  609. *****************************************************************/
  610. BOOL RemoveConv(hwndClientDDE, hwndServerDDE)
  611.     HWND  hwndClientDDE;
  612.     HWND  hwndServerDDE;
  613. {
  614.     struct CONV * pRemoveConv;
  615.     struct CONV * pConv;
  616.     int       nConvIndex;
  617.     
  618.     for (pRemoveConv = Conv, nConvIndex = 0;
  619.      nConvIndex < nConvCount;
  620.      pRemoveConv++, nConvIndex++)
  621.     {
  622.     if (pRemoveConv->hwndClientDDE == hwndClientDDE
  623.         && pRemoveConv->hwndServerDDE == hwndServerDDE)
  624.         break;
  625.     }
  626.     if (nConvIndex >= nConvCount)
  627.         return (FALSE);
  628.     nConvIndex = 0;
  629.     pConv = Conv;
  630.     while (pConv != pRemoveConv)
  631.     {
  632.     if (++nConvIndex >= nConvCount)
  633.             return (FALSE);
  634.     pConv++;
  635.     }
  636.     while (++nConvIndex < nConvCount)
  637.     {
  638.     *pConv = *(pConv+1);
  639.     pConv++;
  640.     }
  641.     nConvCount--;
  642.     return (TRUE);
  643. }
  644.  
  645.  
  646.  
  647.  
  648. /****************************************************************
  649.  
  650.     FUNCTION: SelectNewConvDlgProc
  651.  
  652.     PURPOSE:  Ask the user to select one of multiple conversations
  653.           that were established during a wild card initiate.
  654.  
  655. ****************************************************************/
  656. BOOL FAR PASCAL SelectNewConvDlgProc(hdlg, message, wParam, lParam)
  657.     HWND      hdlg;
  658.     unsigned  message;
  659.     WORD      wParam;
  660.     LONG      lParam;
  661. {
  662.     HWND hctlConvBox;
  663.     struct CONV * pConv;
  664.     int  nConvIndex;
  665.     char szConvInfo[CONVINFO_MAX_SIZE];
  666.     char * pcBlank;
  667.     int    nIndex;
  668.  
  669.     switch (message)
  670.     {
  671.     case WM_INITDIALOG:
  672.         hctlConvBox = GetDlgItem(hdlg, IDC_CONVBOX);
  673.         SendMessage(hctlConvBox, LB_RESETCONTENT, 0, 0L);
  674.         for (pConv = Conv, nConvIndex = 0;
  675.          nConvIndex < nConvCount;
  676.          pConv++, nConvIndex++)
  677.         {
  678.         /* If this is one of the newly initiated conversations */
  679.         /* then add it to the list box.                */
  680.         if (pConv->hwndClientDDE == hwndNewClientDDE)
  681.         {
  682.             /* Display server's DDE window in the list box, */
  683.             /* as that is the only way to distinguish        */
  684.             /* conversations at this point.            */
  685.             itoa((int)pConv->hwndServerDDE, szConvInfo, 16);
  686.             strupr(szConvInfo);
  687.             strcat(szConvInfo, " ");
  688.             strcat(szConvInfo, pConv->szApplication);
  689.             strcat(szConvInfo, " | ");
  690.             strcat(szConvInfo, pConv->szTopic);
  691.  
  692.             SendMessage(hctlConvBox,
  693.             LB_ADDSTRING,
  694.             0,
  695.             (LONG)(LPSTR)szConvInfo);
  696.         }
  697.         }
  698.         return (TRUE);
  699.  
  700.     case WM_COMMAND:
  701.         switch (wParam)
  702.         {
  703.         case IDC_CANCEL:
  704.             /* Function LetUserPickConveresation will terminate */
  705.             /* all newly initiated conversations.        */
  706.             hwndNewServerDDE = NULL;
  707.             EndDialog(hdlg, FALSE);
  708.             return (TRUE);
  709.  
  710.         case IDC_OK:
  711.             /* Function LetUserPickConversation will terminate */
  712.             /* all newly initiated conversations, except the   */
  713.             /* one selected by the user: hwndNewServerDDE.     */
  714.             hwndNewServerDDE = NULL;
  715.             hctlConvBox = GetDlgItem(hdlg, IDC_CONVBOX);
  716.             if ((nIndex = SendMessage(hctlConvBox,
  717.                           LB_GETCURSEL, 0, 0L))
  718.             != LB_ERR)
  719.             {
  720.             szConvInfo[0] = 0;
  721.             SendMessage(hctlConvBox,
  722.                 LB_GETTEXT,
  723.                 nIndex,
  724.                 (LONG)(LPSTR)szConvInfo);
  725.             if (pcBlank = strchr(szConvInfo, ' '))
  726.             {
  727.                 *pcBlank = 0; /* terminate hwnd numeric value */
  728.                 hwndNewServerDDE = HexToInt(szConvInfo);
  729.             }
  730.             }
  731.             EndDialog(hdlg, TRUE);
  732.             return (TRUE);
  733.  
  734.         default:
  735.             return (FALSE);
  736.         }
  737.     }
  738.     return (FALSE);
  739. }
  740.  
  741.  
  742.  
  743. /****************************************************************
  744.  
  745.     FUNCTION: SetConvInTerminateState
  746.  
  747.     PURPOSE:  Set conversation terminate state to TRUE.
  748.  
  749. ****************************************************************/
  750. void SetConvInTerminateState(hwndClientDDE, hwndServerDDE)
  751.     HWND hwndClientDDE;
  752.     HWND hwndServerDDE;
  753. {
  754.     struct CONV * pConv;
  755.     int  nConvIndex;
  756.  
  757.     for (nConvIndex = 0, pConv = Conv;
  758.      nConvIndex < nConvCount;
  759.      nConvIndex++, pConv++)
  760.     {
  761.     if (pConv->hwndClientDDE == hwndClientDDE
  762.         && pConv->hwndServerDDE == hwndServerDDE)
  763.     {
  764.         pConv->bInTerminate = TRUE;
  765.         return;
  766.     }
  767.     }
  768.     return;
  769. }
  770.  
  771.  
  772.  
  773. /****************************************************************
  774.  
  775.     FUNCTION: SetConvItemValue
  776.  
  777.     PURPOSE:  Find server data item and set value.
  778.  
  779. ****************************************************************/
  780. BOOL SetConvItemValue(hwndClientDDE, szItem, lpszValue)
  781.     HWND hwndClientDDE;
  782.     char * szItem;
  783.     LPSTR  lpszValue;
  784. {
  785.    struct ITEM * pItem;
  786.    char        * pcValue;
  787.  
  788.     if (pItem = FindItem(hwndClientDDE, szItem))
  789.     {
  790.         pcValue = pItem->szValue;
  791.         /* copy until <CR> in CF_TEXT data */
  792.         while (*lpszValue != '\r' && *lpszValue)
  793.         {
  794.             *pcValue++ = *lpszValue++;
  795.         }
  796.         *pcValue++ = 0;
  797.     /* Repaint client application window */
  798.     InvalidateRect(hwndMain, NULL, TRUE);
  799.         return (TRUE);
  800.     }
  801.     return (FALSE);
  802. }
  803.  
  804.  
  805.  
  806. /****************************************************************
  807.  
  808.     FUNCTION: SetConvPendingAck
  809.  
  810.     PURPOSE:  Set the state of acknowledgement for a specified
  811.           conversation.
  812.  
  813. ****************************************************************/
  814. void SetConvPendingAck(hwndClientDDE, ePendingAck)
  815.     HWND hwndClientDDE;
  816.     enum PENDINGACK ePendingAck;
  817. {
  818.     struct CONV * pConv;
  819.  
  820.     if (pConv = FindConv(hwndClientDDE))
  821.     {
  822.     pConv->ePendingAck = ePendingAck;
  823.     }
  824.     return;
  825. }
  826.