home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddesrv.zip / IOS2P008.C next >
C/C++ Source or Header  |  1994-08-12  |  49KB  |  951 lines

  1. /* *******************************************************************
  2.    *** File:   IOS2P008.C                                          ***
  3.    *** Author: Harald (HaWi) Wilhelm                               ***
  4.    *** Date:   16.04.1994                                          ***
  5.    ******************************************************************* */
  6. #define  INCL_BASE
  7. #define  INCL_PM
  8. #include <os2.h>
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include "IOS2P008.H"
  15.  
  16. /* *******************************************************************
  17.    *** Function: ClientWndProc                                     ***
  18.    ******************************************************************* */
  19. MRESULT EXPENTRY ClientWndProc (HWND   hwnd,
  20.                                 MSG    msg,
  21.                                 MPARAM mp1,
  22.                                 MPARAM mp2)
  23.    {
  24.    BOOL        f ;
  25.    CONVCONTEXT cctxt ;
  26.    DDECONV     ddeconv ;
  27.    HPS         hps ;
  28.    HWND        hwndTemp ;
  29.    PDDEINIT    pddei ;
  30.    PSTARTUP    pstartup ;
  31.    static PSZ  apszDDETopics [] = { SZDDESYS_TOPIC,                            /* Array of all Topics */
  32.                                     DDEP_TOPIC1,
  33.                                     DDEP_TOPIC2,
  34.                                     DDEP_TOPIC3,
  35.                                     DDEP_TOPIC4,
  36.                                     DDEP_TOPIC5,
  37.                                     DDEP_TOPIC6 } ;
  38.    static PSZ  apszListbox1 [] = { "Listbox1 - Item 1",                        /* Startdata for left Listbox */
  39.                                    "Listbox1 - Item 2",
  40.                                    "Listbox1 - Item 3" } ;
  41.    static PSZ  apszListbox2 [] = { "Listbox2 - Item 1",                        /* Startdata for right Listbox */
  42.                                    "Listbox2 - Item 2",
  43.                                    "Listbox2 - Item 3" } ;
  44.    PWND        pwnd ;
  45.    RECTL       rcl ;
  46.    SHORT       s ;
  47.    ULONG       ulI ;
  48.    ULONG       ulJ ;
  49.    
  50.    pwnd = WinQueryWindowPtr (WinQueryWindow (hwnd,                             /* get pointer to instancedata */
  51.                                              QW_PARENT),
  52.                              QWL_USER) ;
  53.    switch (msg)
  54.       {
  55.       case WM_CLOSE:
  56.          for (ulI = 0;                                                         /* Query all DDE connections for active ones */
  57.               ulI < DDEP_MAXDDELINKS;                                          /* issue a private terminating message */
  58.               ulI++)
  59.             {
  60.             if (pwnd->ahwndDDE [ulI])
  61.                {
  62.                WinSendMsg (pwnd->ahwndDDE [ulI],
  63.                            WMP_DDEDESTROY,
  64.                            MPVOID,
  65.                            MPVOID) ;
  66.                WinDestroyWindow (pwnd->ahwndDDE [ulI]) ;
  67.                }
  68.             }
  69.          WinDestroyWindow (pwnd->hwndListbox1) ;                               /* Destroy left Listbox */
  70.          WinDestroyWindow (pwnd->hwndListbox2) ;                               /* Destroy right listbox */
  71.          WinPostMsg (hwnd,                                                     /* Messageloop breaker */
  72.                      WM_QUIT,
  73.                      MPVOID,
  74.                      MPVOID) ;
  75.          free (pwnd) ;                                                         /* free instancedata */
  76.          return (MRESULT) FALSE ;
  77.       case WM_CONTROL:
  78.          switch (SHORT1FROMMP (mp1))
  79.             {
  80.             case IDL_IOS2P_1:
  81.                switch (SHORT2FROMMP (mp1))
  82.                   {
  83.                   case LN_SELECT:
  84.                      for (ulI = 0;                                             /* If the user selects an item in the left listbox */
  85.                           ulI < DDEP_MAXDDELINKS;                              /* then all active DDE connections are checked */
  86.                           ulI++)                                               /* and informed that DDE data changed */
  87.                         {
  88.                         if (pwnd->ahwndDDE [ulI])
  89.                            {
  90.                            WinPostMsg (pwnd->ahwndDDE [ulI],
  91.                                        WMP_DDEUPDATE,
  92.                                        MPVOID,
  93.                                        MPVOID) ;
  94.                            }
  95.                         }
  96.                      break ;
  97.                   }
  98.                break ;
  99.             }
  100.          break ;
  101.       case WM_CREATE:
  102.          pwnd = calloc (1,                                                     /* allocate instancedata */
  103.                         sizeof (WND)) ;
  104.          WinSetWindowPtr (WinQueryWindow (hwnd,                                /* Place address of instancedata in window words */
  105.                                           QW_PARENT),
  106.                           QWL_USER,
  107.                           pwnd) ;
  108.          WinPostMsg (hwnd,                                                     /* My own start */
  109.                      WMP_CREATE,
  110.                      MPVOID,
  111.                      MPVOID) ;
  112.          break ;
  113.       case WM_DDE_ACK:
  114.          if (PVOIDFROMMP (mp2))                                                /* DDE Client did send ACK */
  115.             {
  116.             DosFreeMem (PVOIDFROMMP (mp2)) ;
  117.             }
  118.          return (MRESULT) TRUE ;
  119.       case WM_DDE_INITIATE:
  120.          pddei = (PDDEINIT) PVOIDFROMMP (mp2) ;                                /* A DDE Request comes in */
  121.          if (!stricmp (DDEP_APPLICATION,                                       /* AppName specified? */
  122.                        pddei->pszAppName))
  123.             {
  124.             f = FALSE ;
  125.             for (ulI = 0;                                                      /* Topicname specified? */
  126.                  ulI < sizeof (apszDDETopics) / sizeof (apszDDETopics [0]);
  127.                  ulI++)
  128.                {
  129.                if (!stricmp (apszDDETopics [ulI],
  130.                              pddei->pszTopic))
  131.                   {
  132.                   f = TRUE ;
  133.                   break ;
  134.                   }
  135.                }
  136.             if (f)                                                             /* Yep! */
  137.                {
  138.                f = FALSE ;
  139.                for (ulI = 0;                                                   /* Is there room for one more DDE connection? */
  140.                     ulI < DDEP_MAXDDELINKS;
  141.                     ulI++)
  142.                   {
  143.                   if (!pwnd->ahwndDDE [ulI])
  144.                      {
  145.                      f = TRUE ;
  146.                      break ;
  147.                      }
  148.                   }
  149.                if (f)                                                          /* Found free place for a new DDE connections */
  150.                   {
  151.                   pwnd->ahwndDDE [ulI] = WinCreateWindow (HWND_OBJECT,         /* Create DDE object window */
  152.                                                           WCP_DDE,
  153.                                                           "",
  154.                                                           WS_DISABLED,
  155.                                                           0,
  156.                                                           0,
  157.                                                           0,
  158.                                                           0,
  159.                                                           HWND_OBJECT,
  160.                                                           HWND_BOTTOM,
  161.                                                           ulI,
  162.                                                           NULL,
  163.                                                           NULL) ;
  164.                   if (pwnd->ahwndDDE [ulI] != NULLHANDLE)                      /* OK? */
  165.                      {
  166.                      strcpy (ddeconv.szTopic,                                  /* Fill in startdata for this DDE object instance */
  167.                              pddei->pszTopic) ;
  168.                      ddeconv.hwndDDEClient = HWNDFROMMP (mp1) ;
  169.                      ddeconv.hwndParent = hwnd ;
  170.                      WinSendMsg (pwnd->ahwndDDE [ulI],
  171.                                  WMP_DDECREATE,
  172.                                  MPFROMP (&ddeconv),
  173.                                  MPVOID) ;
  174.                      memset (&cctxt,
  175.                              0,
  176.                              sizeof (cctxt)) ;
  177.                      cctxt.cb = sizeof (cctxt) ;
  178.                      cctxt.fsContext = DDECTXT_CASESENSITIVE ;
  179.                      cctxt.idCountry = 49 ;
  180.                      cctxt.usCodepage = 850 ;
  181.                      WinDdeRespond (HWNDFROMMP (mp1),                          /* Send ACK to requesting application */
  182.                                     pwnd->ahwndDDE [ulI],
  183.                                     DDEP_APPLICATION,
  184.                                     pddei->pszTopic,
  185.                                     &cctxt) ;
  186.                      }
  187.                   }
  188.                }
  189.             }
  190.          if ((!*pddei->pszAppName) ||                                          /* Empty Appname and empty topicname? */
  191.              (!*pddei->pszTopic))
  192.             {
  193.             for (ulI = 0;                                                      /* Send all topics to requesting application */
  194.                  ulI < sizeof (apszDDETopics) / sizeof (apszDDETopics [0]);    /* There must be one connection per topic */
  195.                  ulI++)                                                        /* Client has to terminate all unwanted topics */
  196.                {
  197.                f = FALSE ;
  198.                for (ulJ = 0;
  199.                     ulJ < DDEP_MAXDDELINKS;
  200.                     ulJ++)
  201.                   {
  202.                   if (!pwnd->ahwndDDE [ulJ])
  203.                      {
  204.                      f = TRUE ;
  205.                      break ;
  206.                      }
  207.                   }
  208.                if (f)
  209.                   {
  210.                   pwnd->ahwndDDE [ulJ] = WinCreateWindow (HWND_OBJECT,
  211.                                                           WCP_DDE,
  212.                                                           "",
  213.                                                           WS_DISABLED,
  214.                                                           0,
  215.                                                           0,
  216.                                                           0,
  217.                                                           0,
  218.                                                           HWND_OBJECT,
  219.                                                           HWND_BOTTOM,
  220.                                                           ulJ,
  221.                                                           NULL,
  222.                                                           NULL) ;
  223.                   if (pwnd->ahwndDDE [ulJ] != NULLHANDLE)
  224.                      {
  225.                      strcpy (ddeconv.szTopic,
  226.                              apszDDETopics [ulI]) ;
  227.                      ddeconv.hwndDDEClient = HWNDFROMMP (mp1) ;
  228.                      ddeconv.hwndParent = hwnd ;
  229.                      WinSendMsg (pwnd->ahwndDDE [ulJ],
  230.                                  WMP_DDECREATE,
  231.                                  MPFROMP (&ddeconv),
  232.                                  MPVOID) ;
  233.                      memset (&cctxt,
  234.                              0,
  235.                              sizeof (cctxt)) ;
  236.                      cctxt.cb = sizeof (cctxt) ;
  237.                      cctxt.fsContext = DDECTXT_CASESENSITIVE ;
  238.                      cctxt.idCountry = 49 ;
  239.                      cctxt.usCodepage = 850 ;
  240.                      WinDdeRespond (HWNDFROMMP (mp1),
  241.                                     pwnd->ahwndDDE [ulJ],
  242.                                     DDEP_APPLICATION,
  243.                                     apszDDETopics [ulI],
  244.                                     &cctxt) ;
  245.                      }
  246.                   }
  247.                }
  248.             }
  249.          return (MRESULT) TRUE ;
  250.       case WM_MINMAXFRAME:
  251.          pwnd->fMinimized = ((PSWP) PVOIDFROMMP (mp1))->fl & SWP_MINIMIZE ;    /* Save Minimized style */
  252.          break ;
  253.       case WM_PAINT:
  254.          hps = WinBeginPaint (hwnd,                                            /* Clear background of client area */
  255.                               NULLHANDLE,
  256.                               &rcl) ;
  257.          WinFillRect (hps,
  258.                       &rcl,
  259.                       SYSCLR_FIELDBACKGROUND) ;
  260.          WinEndPaint (hps) ;
  261.          return (MRESULT) FALSE ;
  262.       case WM_SIZE:
  263.          WinPostMsg (hwnd,                                                     /* Our own PAINT function */
  264.                      WMP_SIZE,
  265.                      MPVOID,
  266.                      MPVOID) ;
  267.          break ;
  268.       case WMP_CREATE:
  269.          WinQueryWindowRect (hwnd,                                             /* Query client size */
  270.                              &rcl) ;
  271.          pwnd->hwndListbox1 = WinCreateWindow (hwnd,                           /* Create left listbox */
  272.                                                WC_LISTBOX,
  273.                                                "",
  274.                                                WS_VISIBLE,
  275.                                                10,
  276.                                                10,
  277.                                                (rcl.xRight - 30) / 2,
  278.                                                rcl.yTop - 20,
  279.                                                pwnd->hwndFrame,
  280.                                                HWND_TOP,
  281.                                                IDL_IOS2P_1,
  282.                                                NULL,
  283.                                                NULL) ;
  284.          for (ulI = 0;                                                         /* Insert initial data into left listbox */
  285.               ulI < sizeof (apszListbox1) / sizeof (apszListbox1 [0]);
  286.               ulI++)
  287.             {
  288.             WinSendMsg (pwnd->hwndListbox1,
  289.                         LM_INSERTITEM,
  290.                         MPFROMSHORT (LIT_END),
  291.                         MPFROMP (apszListbox1 [ulI])) ;
  292.             }
  293.          WinSendMsg (pwnd->hwndListbox1,                                       /* Select first listbox entry */
  294.                      LM_SELECTITEM,
  295.                      MPFROMSHORT (0),
  296.                      MPFROMSHORT (TRUE)) ;
  297.          pwnd->hwndListbox2 = WinCreateWindow (hwnd,                           /* Create right listbox */
  298.                                                WC_LISTBOX,
  299.                                                "",
  300.                                                WS_VISIBLE,
  301.                                                ((rcl.xRight - 30) / 2) + 20,
  302.                                                10,
  303.                                                (rcl.xRight - 30) / 2,
  304.                                                rcl.yTop - 20,
  305.                                                pwnd->hwndFrame,
  306.                                                HWND_TOP,
  307.                                                IDL_IOS2P_2,
  308.                                                NULL,
  309.                                                NULL) ;
  310.          for (ulI = 0;                                                         /* Insert initial data */
  311.               ulI < sizeof (apszListbox2) / sizeof (apszListbox2 [0]);
  312.               ulI++)
  313.             {
  314.             WinSendMsg (pwnd->hwndListbox2,
  315.                         LM_INSERTITEM,
  316.                         MPFROMSHORT (LIT_END),
  317.                         MPFROMP (apszListbox2 [ulI])) ;
  318.             }
  319.          WinSendMsg (pwnd->hwndListbox2,                                       /* Select first row */
  320.                      LM_SELECTITEM,
  321.                      MPFROMSHORT (0),
  322.                      MPFROMSHORT (TRUE)) ;
  323.          return (MRESULT) FALSE ;
  324.       case WMP_DDECOUNT:                                                       /* DDE Client queried it's object window for count of DDE connections */
  325.          ulJ = 0 ;
  326.          for (ulI = 0;
  327.               ulI < DDEP_MAXDDELINKS;
  328.               ulI++)
  329.             {
  330.             if (pwnd->ahwndDDE [ulI])
  331.                {
  332.                ulJ++ ;
  333.                }
  334.             }
  335.          return MRFROMLONG (ulJ) ;
  336.       case WMP_DDEDESTROY:                                                     /* DDE Client terminated it's DDE object */
  337.          WinDestroyWindow (HWNDFROMMP (mp1)) ;                                 /* DDE object window sends this message to free this DDE object */
  338.          for (ulI = 0;
  339.               ulI < DDEP_MAXDDELINKS;
  340.               ulI++)
  341.             {
  342.             if (pwnd->ahwndDDE [ulI] == HWNDFROMMP (mp1))
  343.                {
  344.                pwnd->ahwndDDE [ulI] = NULLHANDLE ;
  345.                break ;
  346.                }
  347.             }
  348.          return (MRESULT) FALSE ;
  349.       case WMP_DELETELISTBOXITEM:                                              /* DDE client want's to delete a listbox entry */
  350.          if (LONGFROMMP (mp1) == IDL_IOS2P_1)                                  /* Left listbox? */
  351.             {
  352.             hwndTemp = pwnd->hwndListbox1 ;                                    /* Yes! */
  353.             }
  354.          else
  355.             {
  356.             hwndTemp = pwnd->hwndListbox2 ;                                    /* Right listbox! */
  357.             }
  358.          WinSendMsg (hwndTemp,                                                 /* Delete item */
  359.                      LM_DELETEITEM,
  360.                      MPFROMSHORT (SHORT1FROMMP (mp2)),
  361.                      MPVOID) ;
  362.          return (MRESULT) FALSE ;
  363.       case WMP_INSERTLISTBOXITEM:                                              /* DDE client want's to insert listbox item */
  364.          if (LONGFROMMP (mp1) == IDL_IOS2P_1)
  365.             {
  366.             hwndTemp = pwnd->hwndListbox1 ;
  367.             }
  368.          else
  369.             {
  370.             hwndTemp = pwnd->hwndListbox2 ;
  371.             }
  372.          WinSendMsg (hwndTemp,                                                 /* Insert text */
  373.                      LM_INSERTITEM,
  374.                      MPFROMSHORT (LIT_END),
  375.                      MPFROMP (PVOIDFROMMP (mp2))) ;
  376.          return (MRESULT) FALSE ;
  377.       case WMP_QUERYLISTBOXITEM:                                               /* DDE client want's currently selected value */
  378.          if (LONGFROMMP (mp1) == IDL_IOS2P_1)
  379.             {
  380.             hwndTemp = pwnd->hwndListbox1 ;
  381.             }
  382.          else
  383.             {
  384.             hwndTemp = pwnd->hwndListbox2 ;
  385.             }
  386.          s = SHORT1FROMMR (WinSendMsg (hwndTemp,                               /* Query index of selected item */
  387.                                        LM_QUERYSELECTION,
  388.                                        MPFROMSHORT (LIT_FIRST),
  389.                                        MPVOID)) ;
  390.          if (s != LIT_NONE)                                                    /* Something selected? */
  391.             {
  392.             WinSendMsg (hwndTemp,                                              /* Yep, return item text */
  393.                         LM_QUERYITEMTEXT,
  394.                         MPFROM2SHORT (s, 64),
  395.                         MPFROMP (PVOIDFROMMP (mp2))) ;
  396.             return MRFROMLONG (FALSE) ;
  397.             }
  398.          else
  399.             {
  400.             return MRFROMLONG (TRUE) ;
  401.             }
  402.       case WMP_SIZE:                                                           /* Resize listboxes */
  403.          if (!pwnd->fMinimized)                                                /* only when window visible */
  404.             {
  405.             WinQueryWindowRect (hwnd,                                          /* Query client size */
  406.                                 &rcl) ;
  407.             WinSetWindowPos (pwnd->hwndListbox1,                               /* Left listbox */
  408.                              HWND_TOP,
  409.                              10,
  410.                              10,
  411.                              (rcl.xRight - 30) / 2,
  412.                              rcl.yTop - 20,
  413.                              SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE) ;
  414.             WinSetWindowPos (pwnd->hwndListbox2,                               /* Right listbox */
  415.                              HWND_TOP,
  416.                              ((rcl.xRight - 30) / 2) + 20,
  417.                              10,
  418.                              (rcl.xRight - 30) / 2,
  419.                              rcl.yTop - 20,
  420.                              SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE) ;
  421.             }
  422.          return (MRESULT) FALSE ;
  423.       case WMP_STARTUP:                                                        /* Startdata from main() */
  424.          pstartup = (PSTARTUP) PVOIDFROMMP (mp1) ;                             /* Copy into instancedata */
  425.          pwnd->hab = pstartup->hab ;
  426.          pwnd->hwndClient = pstartup->hwndClient ;
  427.          pwnd->hwndFrame = pstartup->hwndFrame ;
  428.          return (MRESULT) FALSE ;
  429.       }
  430.    return (WinDefWindowProc (hwnd,
  431.                              msg,
  432.                              mp1,
  433.                              mp2)) ;
  434.    }
  435.  
  436. /* *******************************************************************
  437.    *** Function: DDEWndProc                                        ***
  438.    ******************************************************************* */
  439. MRESULT EXPENTRY DDEWndProc (HWND   hwnd,
  440.                              MSG    msg,
  441.                              MPARAM mp1,
  442.                              MPARAM mp2)
  443.    {
  444.    BOOL       f ;
  445.    CHAR       szBuffer [2048] ;
  446.    PDDECONV   pddeconv ;
  447.    PDDESTRUCT pdde ;
  448.    PDDESTRUCT pddeNew ;
  449.    PWNDDDE    pwnddde ;
  450.    ULONG      ulI ;
  451.    
  452.    pwnddde = WinQueryWindowPtr (hwnd,                                          /* Instancedata from this DDE object window */
  453.                                 QWL_USER) ;
  454.    switch (msg)
  455.       {
  456.       case WM_CREATE:                                                          /* Create a new DDE object window */
  457.          pwnddde = calloc (1,                                                  /* allocate instance data for this DDE object */
  458.                            sizeof (WNDDDE)) ;
  459.          WinSetWindowPtr (hwnd,                                                /* Save pointer in window words */
  460.                           QWL_USER,
  461.                           pwnddde) ;
  462.          break ;
  463.       case WM_DDE_ACK:                                                         /* DDE client sends ACK */
  464.          if (PVOIDFROMMP (mp2))
  465.             {
  466.             DosFreeMem (PVOIDFROMMP (mp2)) ;
  467.             }
  468.          return (MRESULT) FALSE ;
  469.       case WM_DDE_ADVISE:                                                      /* Automatic DDE connection requested */
  470.          if (!PVOIDFROMMP (mp2))                                               /* Oops, no data */
  471.             {
  472.             return (MRESULT) FALSE ;
  473.             }
  474.          pwnddde->ulRequestType = msg ;                                        /* Save type of connection (ADVISE) */
  475.          pwnddde->hwndDDEClient = HWNDFROMMP (mp1) ;
  476.          pdde = (PDDESTRUCT) PVOIDFROMMP (mp2) ;                               /* Get DDE struct */
  477.          f = FALSE ;
  478.          strcpy (pwnddde->szItemName,                                          /* Copy itemname in instance data */
  479.                  DDES_PSZITEMNAME (pdde)) ;
  480.          if (!stricmp (DDEP_TOPIC1,                                            /* This topic allows ADVISE connection */
  481.                        pwnddde->szTopic))
  482.             {
  483.             f = TRUE ;
  484.             }
  485.          if (f)                                                                /* ADVISE connection is allowed */
  486.             {
  487.             pwnddde->fImmediate = (pdde->fsStatus & DDE_FNODATA) ? FALSE : TRUE ; /* If update of data ACK or direct send data to client? */
  488.             if (pdde->fsStatus & DDE_FACKREQ)                                  /* DDE client want's ACK if ADVISE possible */
  489.                {
  490.                pddeNew = MakeDDESeg (HWNDFROMMP (mp1),
  491.                                      DDES_PSZITEMNAME (pdde),
  492.                                      DDE_FACK,
  493.                                      CF_TEXT,
  494.                                      NULL,
  495.                                      0) ;
  496.                WinDdePostMsg (HWNDFROMMP (mp1),
  497.                               hwnd,
  498.                               WM_DDE_ACK,
  499.                               pddeNew,
  500.                               DDEPM_RETRY) ;
  501.                }
  502.             }
  503.          else                                                                  /* Negative ACK because requested Topic does not allow ADVISE */
  504.             {
  505.             pddeNew = MakeDDESeg (HWNDFROMMP (mp1),
  506.                                   DDES_PSZITEMNAME (pdde),
  507.                                   DDE_NOTPROCESSED,
  508.                                   CF_TEXT,
  509.                                   NULL,
  510.                                   0) ;
  511.             WinDdePostMsg (HWNDFROMMP (mp1),
  512.                            hwnd,
  513.                            WM_DDE_ACK,
  514.                            pddeNew,
  515.                            DDEPM_RETRY) ;
  516.             }
  517.          DosFreeMem (pdde) ;
  518.          return (MRESULT) FALSE ;
  519.       case WM_DDE_POKE:                                                        /* DDE client sends data */
  520.          if (!PVOIDFROMMP (mp2))
  521.             {
  522.             return (MRESULT) FALSE ;
  523.             }
  524.          pwnddde->ulRequestType = msg ;                                        /* Save type of connection (POKE) */
  525.          pwnddde->hwndDDEClient = HWNDFROMMP (mp1) ;
  526.          pdde = (PDDESTRUCT) PVOIDFROMMP (mp2) ;                               /* Get DDE struct */
  527.          f = FALSE ;
  528.          if (!stricmp (DDEP_TOPIC3,                                            /* Insert in left listbox? */
  529.                        pwnddde->szTopic))
  530.             {
  531.             f = TRUE ;                                                         /* Yes! */
  532.             WinSendMsg (pwnddde->hwndParent,                                   /* Send this to client window */
  533.                         WMP_INSERTLISTBOXITEM,
  534.                         MPFROMLONG (IDL_IOS2P_1),
  535.                         MPFROMP (DDES_PABDATA (pdde))) ;
  536.             }
  537.          if (!stricmp (DDEP_TOPIC4,                                            /* Insert in right listbox? */
  538.                        pwnddde->szTopic))
  539.             {
  540.             f = TRUE ;                                                         /* Yes! */
  541.             WinSendMsg (pwnddde->hwndParent,                                   /* Send this to client window */
  542.                         WMP_INSERTLISTBOXITEM,
  543.                         MPFROMLONG (IDL_IOS2P_2),
  544.                         MPFROMP (DDES_PABDATA (pdde))) ;
  545.             }
  546.          if (!stricmp (DDEP_TOPIC5,                                            /* Delete item from left listbox? */
  547.                        pwnddde->szTopic))
  548.             {
  549.             f = TRUE ;                                                         /* Yes! */
  550.             WinSendMsg (pwnddde->hwndParent,                                   /* Send this to client window */
  551.                         WMP_DELETELISTBOXITEM,
  552.                         MPFROMLONG (IDL_IOS2P_1),
  553.                         MPFROMSHORT (atol (DDES_PABDATA (pdde)))) ;
  554.             }
  555.          if (!stricmp (DDEP_TOPIC6,                                            /* Delete item from right listbox? */
  556.                        pwnddde->szTopic))
  557.             {
  558.             f = TRUE ;                                                         /* Yes! */
  559.             WinSendMsg (pwnddde->hwndParent,                                   /* Send this to client window */
  560.                         WMP_DELETELISTBOXITEM,
  561.                         MPFROMLONG (IDL_IOS2P_2),
  562.                         MPFROMSHORT (atol (DDES_PABDATA (pdde)))) ;
  563.             }
  564.          if (f)                                                                /* Everything's allowed */
  565.             {
  566.             if (pdde->fsStatus & DDE_FACKREQ)                                  /* ACK requested? */
  567.                {
  568.                pddeNew = MakeDDESeg (HWNDFROMMP (mp1),                         /* Yes */
  569.                                      DDES_PSZITEMNAME (pdde),
  570.                                      DDE_FACK,
  571.                                      CF_TEXT,
  572.                                      DDES_PABDATA (pdde),
  573.                                      strlen (DDES_PABDATA (pdde)) + 1) ;
  574.                WinDdePostMsg (HWNDFROMMP (mp1),
  575.                               hwnd,
  576.                               WM_DDE_ACK,
  577.                               pddeNew,
  578.                               DDEPM_RETRY) ;
  579.                }
  580.             }
  581.          else                                                                  /* Don't know requested DDE topic */
  582.             {
  583.             pddeNew = MakeDDESeg (HWNDFROMMP (mp1),                            /* Negative ACK */
  584.                                   DDES_PSZITEMNAME (pdde),
  585.                                   DDE_NOTPROCESSED,
  586.                                   CF_TEXT,
  587.                                   DDES_PABDATA (pdde),
  588.                                   strlen (DDES_PABDATA (pdde)) + 1) ;
  589.             WinDdePostMsg (HWNDFROMMP (mp1),
  590.                            hwnd,
  591.                            WM_DDE_ACK,
  592.                            pddeNew,
  593.                            DDEPM_RETRY) ;
  594.             }
  595.          DosFreeMem (PVOIDFROMMP (mp2)) ;
  596.          return (MRESULT) FALSE ;
  597.       case WM_DDE_REQUEST:                                                     /* DDE request from DDE client */
  598.          if (!PVOIDFROMMP (mp2))
  599.             {
  600.             return (MRESULT) FALSE ;
  601.             }
  602.          pwnddde->ulRequestType = msg ;                                        /* Save type of connection (REQUEST) */
  603.          pwnddde->hwndDDEClient = HWNDFROMMP (mp1) ;
  604.          pdde = (PDDESTRUCT) PVOIDFROMMP (mp2) ;                               /* Get DDE struct */
  605.          f = FALSE ;
  606.          if (!stricmp (SZDDESYS_ITEM_FORMATS,                                  /* System Topic "Formats" */
  607.                        DDES_PSZITEMNAME (pdde)))
  608.             {
  609.             f = TRUE ;
  610.             strcpy (szBuffer,                                                  /* TAB delimited text is allowed */
  611.                     SZFMT_TEXT) ;
  612.             }
  613.          if (!stricmp (SZDDESYS_ITEM_HELP,                                     /* System Topic "Help" */
  614.                        DDES_PSZITEMNAME (pdde)))
  615.             {
  616.             f = TRUE ;
  617.             strcpy (szBuffer,                                                  /* Send something back */
  618.                     "Helptext for DDE") ;
  619.             }
  620.          if (!stricmp (SZDDESYS_ITEM_RESTART,                                  /* System Topic "Restart" */
  621.                        DDES_PSZITEMNAME (pdde)))
  622.             {
  623.             f = TRUE ;                                                         /* Send AppName back */
  624.             strcpy (szBuffer,
  625.                     "IOS2P008.EXE") ;
  626.             }
  627.          if (!stricmp (SZDDESYS_ITEM_STATUS,                                   /* System Topic "Status" */
  628.                        DDES_PSZITEMNAME (pdde)))
  629.             {
  630.             f = TRUE ;
  631.             ulI = LONGFROMMR (WinSendMsg (pwnddde->hwndParent,                 /* Query count of DDE connections from client window */
  632.                                           WMP_DDECOUNT,
  633.                                           MPVOID,
  634.                                           MPVOID)) ;
  635.             sprintf (szBuffer,                                                 /* Send count back */
  636.                      "%s%u",
  637.                      "Active DDE Connections: ",
  638.                      ulI) ;
  639.             }
  640.          if (!stricmp (SZDDESYS_ITEM_SYSITEMS,                                 /* System Topic "SysItems" */
  641.                        DDES_PSZITEMNAME (pdde)))
  642.             {
  643.             f = TRUE ;                                                         /* Send all SysItems */
  644.             sprintf (szBuffer,
  645.                      "%s\t%s\t%s\t%s\t%s\t%s",
  646.                      SZDDESYS_ITEM_FORMATS,
  647.                      SZDDESYS_ITEM_HELP,
  648.                      SZDDESYS_ITEM_RESTART,
  649.                      SZDDESYS_ITEM_STATUS,
  650.                      SZDDESYS_ITEM_SYSITEMS,
  651.                      SZDDESYS_ITEM_TOPICS) ;
  652.             }
  653.          if (!stricmp (SZDDESYS_ITEM_TOPICS,                                   /* System Topic "Topics" */
  654.                        DDES_PSZITEMNAME (pdde)))
  655.             {
  656.             f = TRUE ;                                                         /* Send all Topics */
  657.             sprintf (szBuffer,
  658.                      "%s\t%s\t%s\t%s\t%s\t%s\t%s",
  659.                      SZDDESYS_TOPIC,
  660.                      DDEP_TOPIC1,
  661.                      DDEP_TOPIC2,
  662.                      DDEP_TOPIC3,
  663.                      DDEP_TOPIC4,
  664.                      DDEP_TOPIC5,
  665.                      DDEP_TOPIC6) ;
  666.             }
  667.          if (f)                                                                /* Valid System Item encountered */
  668.             {
  669.             pddeNew = MakeDDESeg (HWNDFROMMP (mp1),                            /* Positive ACK */
  670.                                   DDES_PSZITEMNAME (pdde),
  671.                                   DDE_FRESPONSE,
  672.                                   CF_TEXT,
  673.                                   szBuffer,
  674.                                   strlen (szBuffer) + 1) ;
  675.             WinDdePostMsg (HWNDFROMMP (mp1),
  676.                            hwnd,
  677.                            WM_DDE_DATA,
  678.                            pddeNew,
  679.                            DDEPM_RETRY) ;
  680.             DosFreeMem (pdde) ;
  681.             return (MRESULT) FALSE ;
  682.             }
  683.          f = FALSE ;                                                           /* Now look for our own topics */
  684.          if (!stricmp (DDEP_TOPIC1,                                            /* Query item from left listbox */
  685.                        pwnddde->szTopic))
  686.             {
  687.             if (!LONGFROMMR (WinSendMsg (pwnddde->hwndParent,                  /* Get data from client window */
  688.                                          WMP_QUERYLISTBOXITEM,
  689.                                          MPFROMLONG (IDL_IOS2P_1),
  690.                                          MPFROMP (szBuffer))))
  691.                {
  692.                f = TRUE ;
  693.                }
  694.             }
  695.          if (!stricmp (DDEP_TOPIC2,                                            /* Query item from right listbox */
  696.                        pwnddde->szTopic))
  697.             {
  698.             if (!LONGFROMMR (WinSendMsg (pwnddde->hwndParent,                  /* Get data from client window */
  699.                                          WMP_QUERYLISTBOXITEM,
  700.                                          MPFROMLONG (IDL_IOS2P_2),
  701.                                          MPFROMP (szBuffer))))
  702.                {
  703.                f = TRUE ;
  704.                }
  705.             }
  706.          if (f)
  707.             {
  708.             pddeNew = MakeDDESeg (HWNDFROMMP (mp1),                            /* Send data to DDE client */
  709.                                   DDES_PSZITEMNAME (pdde),
  710.                                   DDE_FRESPONSE,
  711.                                   CF_TEXT,
  712.                                   szBuffer,
  713.                                   strlen (szBuffer) + 1) ;
  714.             WinDdePostMsg (HWNDFROMMP (mp1),
  715.                            hwnd,
  716.                            WM_DDE_DATA,
  717.                            pddeNew,
  718.                            DDEPM_RETRY) ;
  719.             }
  720.          else                                                                  /* Error */
  721.             {
  722.             pddeNew = MakeDDESeg (HWNDFROMMP (mp1),                            /* Negative ACK */
  723.                                   DDES_PSZITEMNAME (pdde),
  724.                                   DDE_NOTPROCESSED,
  725.                                   CF_TEXT,
  726.                                   NULL,
  727.                                   0) ;
  728.             WinDdePostMsg (HWNDFROMMP (mp1),
  729.                            hwnd,
  730.                            WM_DDE_ACK,
  731.                            pddeNew,
  732.                            DDEPM_RETRY) ;
  733.             }
  734.          DosFreeMem (pdde) ;
  735.          return (MRESULT) FALSE ;
  736.       case WM_DDE_TERMINATE:                                                   /* DDE client stops connection */
  737.          WinDdePostMsg (HWNDFROMMP (mp1),                                      /* Always ACK */
  738.                         hwnd,
  739.                         WM_DDE_TERMINATE,
  740.                         NULL,
  741.                         DDEPM_RETRY) ;
  742.          WinPostMsg (pwnddde->hwndParent,                                      /* Inform client window to free blocked connection */
  743.                      WMP_DDEDESTROY,
  744.                      MPFROMHWND (hwnd),
  745.                      MPVOID) ;
  746.          return (MRESULT) FALSE ;
  747.       case WM_DDE_UNADVISE:                                                    /* No longer ADVISE */
  748.          if (PVOIDFROMMP (mp2))
  749.             {
  750.             pdde = (PDDESTRUCT) PVOIDFROMMP (mp2) ;                            /* Get DDE Struct */
  751.             if (pdde->fsStatus & DDE_FACKREQ)                                  /* ACK? */
  752.                {
  753.                pddeNew = MakeDDESeg (HWNDFROMMP (mp1),                         /* Yes */
  754.                                      DDES_PSZITEMNAME (pdde),
  755.                                      DDE_FACK,
  756.                                      CF_TEXT,
  757.                                      NULL,
  758.                                      0) ;
  759.                WinDdePostMsg (HWNDFROMMP (mp1),
  760.                               hwnd,
  761.                               WM_DDE_ACK,
  762.                               pddeNew,
  763.                               DDEPM_RETRY) ;
  764.                }
  765.             pwnddde->ulRequestType = 0 ;                                       /* Free connection type ... just in case */
  766.             DosFreeMem (pdde) ;
  767.             }
  768.          return (MRESULT) FALSE ;
  769.       case WM_DESTROY:                                                         /* DDE object window deleted */
  770.          free (pwnddde) ;                                                      /* free instance data for this connection */
  771.          break ;
  772.       case WMP_DDECREATE:                                                      /* Startdata from client window */
  773.          pddeconv = (PDDECONV) PVOIDFROMMP (mp1) ;
  774.          pwnddde->hwndParent = pddeconv->hwndParent ;                          /* Handle of Parent (Client window) */
  775.          pwnddde->hwndDDEClient = pddeconv->hwndDDEClient ;                    /* HWND of DDE Partner */
  776.          strcpy (pwnddde->szTopic,                                             /* Requested topic */
  777.                  pddeconv->szTopic) ;
  778.          return (MRESULT) FALSE ;
  779.       case WMP_DDEDESTROY:                                                     /* Application terminated. Client window want's DDE object to terminate connection */
  780.          WinDdePostMsg (pwnddde->hwndDDEClient,
  781.                         hwnd,
  782.                         WM_DDE_TERMINATE,
  783.                         NULL,
  784.                         DDEPM_RETRY) ;
  785.          return (MRESULT) FALSE ;
  786.       case WMP_DDEUPDATE:                                                      /* Application data changed (in client window) */
  787.          if (pwnddde->ulRequestType == WM_DDE_ADVISE)                          /* Do we hold an ADVISE connection? */
  788.             {
  789.             f = FALSE ;                                                        /* Yes! */
  790.             if (!stricmp (DDEP_TOPIC1,                                         /* Only for this topic allowed */
  791.                           pwnddde->szTopic))
  792.                {
  793.                f = TRUE ;                                                      /* Query data from client window */
  794.                WinSendMsg (pwnddde->hwndParent,
  795.                            WMP_QUERYLISTBOXITEM,
  796.                            MPFROMLONG (IDL_IOS2P_1),
  797.                            MPFROMP (szBuffer)) ;
  798.                }
  799.             if (f)
  800.                {
  801.                if (pwnddde->fImmediate)                                        /* ACK or data to DDE client? */
  802.                   {
  803.                   pddeNew = MakeDDESeg (pwnddde->hwndDDEClient,                /* Send data immediately */
  804.                                         pwnddde->szItemName,
  805.                                         0,
  806.                                         CF_TEXT,
  807.                                         szBuffer,
  808.                                         strlen (szBuffer) + 1) ;
  809.                   WinDdePostMsg (pwnddde->hwndDDEClient,
  810.                                  hwnd,
  811.                                  WM_DDE_DATA,
  812.                                  pddeNew,
  813.                                  DDEPM_RETRY) ;
  814.                   }
  815.                else                                                            /* DDE Client want's ACK when data changes */
  816.                   {
  817.                   pddeNew = MakeDDESeg (pwnddde->hwndDDEClient,
  818.                                         pwnddde->szItemName,
  819.                                         DDE_FNODATA,
  820.                                         CF_TEXT,
  821.                                         NULL,
  822.                                         0) ;
  823.                   WinDdePostMsg (pwnddde->hwndDDEClient,
  824.                                  hwnd,
  825.                                  WM_DDE_DATA,
  826.                                  pddeNew,
  827.                                  DDEPM_RETRY) ;
  828.                   }
  829.                }
  830.             }
  831.          return (MRESULT) FALSE ;
  832.       }
  833.    return WinDefWindowProc (hwnd,
  834.                             msg,
  835.                             mp1,
  836.                             mp2) ;
  837.    }
  838.  
  839. /* *******************************************************************
  840.    *** Function: main                                              ***
  841.    ******************************************************************* */
  842. INT main (VOID)                                                                /*  Application start */
  843.    {
  844.    HMQ          hmq ;
  845.    PSTARTUP     pstartup ;
  846.    QMSG         qmsg ;
  847.    static ULONG ulCreateFlags = FCF_MINMAX | FCF_SIZEBORDER |
  848.                                 FCF_SHELLPOSITION | FCF_TITLEBAR |
  849.                                 FCF_SYSMENU | FCF_TASKLIST ;
  850.    
  851.    if ((pstartup = calloc (1,                                                  /* Startup values for Client proc */
  852.                            sizeof (STARTUP))) != (PSTARTUP) NULL)
  853.       {
  854.       if ((pstartup->hab = WinInitialize (QV_OS2)) != NULLHANDLE)              /* Hello PM */
  855.          {
  856.          if ((hmq = WinCreateMsgQueue (pstartup->hab,                          /* Create Messagequeue */
  857.                                        0)) != NULLHANDLE)
  858.             {
  859.             if (WinRegisterClass (pstartup->hab,                               /* Register Class for DDE Objectwindows */
  860.                                   WCP_DDE,
  861.                                   (PFNWP) DDEWndProc,
  862.                                   0,
  863.                                   sizeof (PVOID)))                             /* Additional memory for DDE instancedata pointer */
  864.                {
  865.                if (WinRegisterClass (pstartup->hab,                            /* Register application */
  866.                                      WCP_IOS2P,
  867.                                      (PFNWP) ClientWndProc,
  868.                                      CS_SIZEREDRAW | CS_SAVEBITS,
  869.                                      0))
  870.                   {
  871.                   if ((pstartup->hwndFrame = WinCreateStdWindow (HWND_DESKTOP, /* Create Standard window */
  872.                                                                  WS_VISIBLE | WS_ANIMATE,
  873.                                                                  &ulCreateFlags,
  874.                                                                  WCP_IOS2P,
  875.                                                                  "",
  876.                                                                  0,
  877.                                                                  NULLHANDLE,
  878.                                                                  IDW_IOS2P,
  879.                                                                  &pstartup->hwndClient)) != NULLHANDLE)
  880.                      {
  881.                      WinSendMsg (pstartup->hwndClient,                         /* Send initial data to client window proc */
  882.                                  WMP_STARTUP,
  883.                                  MPFROMP (pstartup),
  884.                                  MPVOID) ;
  885.                      while (WinGetMsg (pstartup->hab,                          /* Message loop */
  886.                                        &qmsg,
  887.                                        0,
  888.                                        0,
  889.                                        0))
  890.                         {
  891.                         WinDispatchMsg (pstartup->hab,
  892.                                         &qmsg) ;
  893.                         }
  894.                      WinDestroyWindow (pstartup->hwndFrame) ;                  /* Destroy application frame */
  895.                      }
  896.                   }
  897.                }
  898.             WinDestroyMsgQueue (hmq) ;                                         /* Delete Message queue */
  899.             }
  900.          WinTerminate (pstartup->hab) ;                                        /* Bye PM */
  901.          }
  902.       free (pstartup) ;                                                        /* Free startup data area */
  903.       }
  904.    return 0 ;
  905.    }
  906.  
  907. /* *******************************************************************
  908.    *** Function: MakeDDESeg                                        ***
  909.    ******************************************************************* */
  910. PDDESTRUCT MakeDDESeg (HWND  hwndDest,                                         /* This function allocates memory for the DDE data area */
  911.                        PSZ   pszItemName,
  912.                        ULONG ulStatus,
  913.                        ULONG ulFormat,
  914.                        PVOID pvData,
  915.                        ULONG ulDataLen)
  916.    {
  917.    PDDESTRUCT pdde ;
  918.    PID        pid ;
  919.    TID        tid ;
  920.    ULONG      ul ;
  921.    ULONG      ulTotal ;
  922.  
  923.    ul = strlen (pszItemName) + 1 ;                                             /* Lenght Itemname + terminating \0 */
  924.    ulTotal = sizeof (DDESTRUCT) + ul + ulDataLen ;                             /* sizeof DDE data area plus sizeof data */
  925.    if (!DosAllocSharedMem ((PPVOID) &pdde,                                     /* allocate SharedMemory for DDE data area */
  926.                            NULL,
  927.                            ulTotal,
  928.                            PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE))
  929.       {
  930.       WinQueryWindowProcess (hwndDest,                                         /* Query receiving process */
  931.                              &pid,
  932.                              &tid) ;
  933.       DosGiveSharedMem (&pdde,                                                 /* allow this process access to this SharedMemory */
  934.                         pid,
  935.                         PAG_READ | PAG_WRITE) ;
  936.       pdde->cbData = ulDataLen ;                                               /* copy data into DDE data area */
  937.       pdde->fsStatus = ulStatus ;
  938.       pdde->usFormat = ulFormat ;
  939.       pdde->offszItemName = sizeof (DDESTRUCT) ;
  940.       pdde->offabData = (ulDataLen && pvData) ? sizeof (DDESTRUCT) + ul : 0 ;
  941.       memcpy (DDES_PSZITEMNAME (pdde),
  942.               pszItemName,
  943.               strlen (pszItemName) + 1) ;
  944.       memcpy (DDES_PABDATA (pdde),
  945.               pvData,
  946.               ulDataLen) ;
  947.       return pdde ;                                                            /* return DDE data area */
  948.       }
  949.    return NULL ;                                                               /* error */
  950.    }
  951.