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